package com.quanquan.store.service;

import DTO.PageDTO;
import DTO.image.Image;
import DTO.image.ImageDTO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.quanquan.store.configBean.RabbitSender;
import com.quanquan.store.dto.ActivityDTO;
import com.quanquan.store.dto.IdDTO;
import com.quanquan.store.entity.Activity;
import com.quanquan.store.entity.Store;
import com.quanquan.store.exception.ActivityException;
import com.quanquan.store.exception.StoreException;
import com.quanquan.store.repository.ActivityRepository;
import com.quanquan.store.request.ActivityRequest;
import commond.ImageOutPut;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import utils.DateUtils;
import utils.StringUtil;
import utils.UUIDGenerator;

import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述: 活动管理逻辑层
 *
 * @ClassName: ActivityService
 * @Author: aasdddddxiaoqianh丶
 * @Date: 2019-03-26 17:28
 * @Version: V1.0
 */
@Service
public class ActivityService {
    private final static String OWNERNAME = "自定义";

    private final static String STORETYPE = "store";//商铺

    //舞台
    private final static String PROMOTION = "stage";
    //主题
    private final static String THEME = "theme";
    //报名
    private final static String APPLY = "apply";

    private final static String PAY = "pay";//支付

    private final static String RECOMMEND = "1";//热门

    private final static String SHOWACT = "0";

    private final static String PREPARING = "preparing";

    private final static String OVER = "over";

    private final static String PROCESSING = "processing";

    private final ActivityRepository activityRepository;

    private final ActivityApplyService activityApplyService;

    @Value("${jump-partams.url}")
    private String activityJumpUrl;

    private final StoreService storeService;
    private final RabbitSender rabbitSender;
    private final RestTemplate restTemplate;

    @Autowired
    public ActivityService(ActivityRepository activityRepository, StoreService storeService, RabbitSender rabbitSender, RestTemplate restTemplate, ActivityApplyService activityApplyService) {
        this.activityRepository = activityRepository;
        this.storeService = storeService;
        this.rabbitSender = rabbitSender;
        this.restTemplate = restTemplate;
        this.activityApplyService = activityApplyService;
    }

    /**
     * 创建活动
     *
     * @param requestBody
     * @return
     */
    public String createActivity(ActivityRequest requestBody) {
        Activity activity = new Activity();
        String foreignKeyType = requestBody.getForeignKeyType();
        String foreignKeyId = requestBody.getForeignKeyId();
        String placed = requestBody.getPlaced();
        //其他活动
        if (StringUtils.isEmpty(foreignKeyId) && StringUtils.isEmpty(foreignKeyType)) {
            activity.setLongitude(requestBody.getLongitude());
            activity.setLatitude(requestBody.getLatitude());
            activity.setOwnershipName(OWNERNAME);
            activity.setForeignKeyType(OWNERNAME);
        } else if (foreignKeyType.equals(STORETYPE)) {
            //判断活动是景点活动还是商铺活动
            Store store = null;
            try {
                store = storeService.findStoreByStoreId(foreignKeyId);
            } catch (StoreException e) {
                e.printStackTrace();
            }

            activity.setLongitude(store.getStoreLongitude());
            activity.setLatitude(store.getStoreLatitude());
            activity.setOwnershipName(store.getStoreName());
            activity.setForeignKeyType(requestBody.getForeignKeyType());
            activity.setAdminId(store.getAdminId());


        }
        if (StringUtil.isEmpty(placed)) {
            activity.setPlaced("store");
        } else {
            activity.setPlaced(placed);
        }

        //查看活动状态
        Date startTime = DateUtils.parseStr2Date("yyyy-MM-dd", requestBody.getStartTime());
        Date endTime = DateUtils.parseStr2Date("yyyy-MM-dd", requestBody.getEndTime());
        Date nowTime = new Date();

        if (nowTime.before(startTime)) {
            //状态准备中
            activity.setActivityStatus(Activity.ActivityStatus.preparing);
        } else if (nowTime.after(endTime)) {
            activity.setActivityStatus(Activity.ActivityStatus.over);

        } else {
            activity.setActivityStatus(Activity.ActivityStatus.processing);
        }

        if (StringUtils.isEmpty(requestBody.getActivityId())) {
            //root账户新建活动
            activity.setId(UUIDGenerator.getUUID());
        } else {
            //商户新建活动
            activity.setId(requestBody.getActivityId());
        }

        activity.setActivityName(requestBody.getActivityName());


        //判断活动类型
        switch (requestBody.getActivityType()) {
            case PROMOTION:
                activity.setActivityType(Activity.ActivityTypes.stage); //促销
                break;
            case THEME:
                activity.setActivityType(Activity.ActivityTypes.theme);//主题
                break;
            default:
                activity.setActivityType(Activity.ActivityTypes.apply);//报名
                activity.setPeopleNum(requestBody.getPeopleNum());
                activity.setLevelStratum(requestBody.getLevelStratum());
                break;
        }

        //根据活动类型设置支付状态
        if (PAY.equals(requestBody.getPay())) {
            activity.setPay(1);
            activity.setActivityPrice(requestBody.getActivityPrice());
            activity.setActivityUrl(requestBody.getActivityUrl());
        } else {
            activity.setPay(0);
        }
        //判断活动是否热门
        if (RECOMMEND.equals(requestBody.getRecommend())) {
            activity.setRecommend(1);
        } else {
            activity.setRecommend(0);
        }
        activity.setSendCoupon(requestBody.getSendCoupon());
        activity.setCouponId(requestBody.getCouponId());
        activity.setPosition(requestBody.getPosition());
        activity.setStartTime(requestBody.getStartTime());
        activity.setEndTime(requestBody.getEndTime());
        activity.setActivityContent(requestBody.getActivityContent());
        //判断是否显示
        if (SHOWACT.equals(requestBody.getShow())) {
            activity.setShow(0);
        } else {
            activity.setShow(1);
        }
        activity.setRemove(0);
        activity.setCreateTime(DateUtils.currentDate());
        activity.setUpdateTime(DateUtils.currentDate());
        activity.setForeignKeyId(requestBody.getForeignKeyId());
        activity.setTimeRule(requestBody.getTimeRule());
        activity.setCoverUrl(requestBody.getCoverUrl());

        Integer shareState = requestBody.getShareState();
        activity.setShareState(shareState);
        if (shareState == 1) {
            activity.setShareUrl(requestBody.getShareUrl());
        }
        String s = activityJumpUrl + activity.getId();
        activity.setJumpUrl(s);
        activityRepository.save(activity);

        bandingImageShip(activity.getId(), requestBody.getImageId());

        return "添加活动成功";


    }

    /**
     * 绑定用户头像
     *
     * @param userId
     * @param imageId
     */
    private void bandingImageShip(String userId, String imageId) {
        ImageOutPut imageOutPut = new ImageOutPut();
        List<String> imageIds = new ArrayList<>();
        imageIds.add(imageId);
        imageOutPut.setForeignKeyId(userId);
        imageOutPut.setImageSource("activity");

//        //通过mq消息队列发送给资源模块绑定图片关系
//        amqpTemplate.convertAndSend("image.exchange", "image.activity", JsonUtil.toJson(imageOutPut));

        Map<String, Object> properties = new HashMap<>();
        properties.put("imageIds", imageIds);
        String exchange = "image.exchange";
        String routingKey = "image.activity";

        rabbitSender.sendMessageToMQ(imageOutPut, properties, exchange, routingKey);
    }


    /**
     * @param page           根据条件查询
     * @param size
     * @param activityStatus
     * @return
     */
    public List<Activity> allActivity(Integer page, Integer size, String activityStatus, String recommend, String placed) {


        List<Activity> list = null;
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);
        Activity activity = new Activity();
        activity.setShow(0);
        activity.setRemove(0);
        if (!StringUtils.isEmpty(activityStatus)) {
            switch (activityStatus) {
                case PREPARING:
                    activity.setActivityStatus(Activity.ActivityStatus.preparing);
                    break;
                case PROCESSING:
                    activity.setActivityStatus(Activity.ActivityStatus.processing);
                    break;
                case OVER:
                    activity.setActivityStatus(Activity.ActivityStatus.over);
                    break;
                default:

            }

        }
        if (StringUtil.isNotEmpty(placed)) {
            activity.setPlaced(placed);
        }
        if (StringUtil.isNotEmpty(recommend)) {
            activity.setRecommend(1);
        }
        Example<Activity> example = Example.of(activity);
        Page<Activity> findAll = activityRepository.findAll(example, pageable);
        list = findAll.getContent();

        return list;
    }


    /**
     * 查询活动详情
     *
     * @param activityId
     * @return
     */
    public ActivityDTO queryActivityDetails(String activityId, String userId) throws ActivityException {

        Activity activity = activityRepository.findByIdAndRemove(activityId, 0);
        if (activity == null) {
            throw new ActivityException("活动不存在");
        }
        //根据活动id去获取图片
        String foreignKeyId = activity.getId();

        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyId(foreignKeyId);
        //去resource模块查询图片
        ImageDTO imageDTO = restTemplate.postForObject("http://QUANQUAN-RESOURCE/image/image_query", idDTO, ImageDTO.class);
        List<Image> images = imageDTO.getImageDTOs();
        //取出活动封面
        Image coverImage = images.stream().filter(i -> i.getCover().equals(true)).findAny().orElse(null);
        if (coverImage != null) {
            activity.setCoverUrl(coverImage.getImageAddress());
        }


        activityRepository.save(activity);
        ActivityDTO activityDTO = new ActivityDTO();
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(activity, activityDTO);

        String activityType = activity.getActivityType().toString();
        if (activityType.equals(APPLY)) {
            Boolean aBoolean = activityApplyService.checkApply(userId, activityId);
            activityDTO.setStatus_apply(aBoolean);
            activityDTO.setActivityType(activityType);
        } else {
            activityDTO.setStatus_apply(false);
        }
        Date startTime = DateUtils.strToDate(activity.getStartTime(), DateUtils.DATE);
        Date endTime = DateUtils.strToDate(activity.getEndTime(), DateUtils.DATE);
        Date nowTime = new Date();
        if (nowTime.before(startTime)) {
            activity.setActivityStatus(Activity.ActivityStatus.preparing);
            activityDTO.setActivityStatus("preparing");
        } else if (nowTime.after(endTime)) {
            activity.setActivityStatus(Activity.ActivityStatus.over);
            activity.setRecommend(0);
            activityDTO.setActivityStatus("over");
        } else {
            activity.setActivityStatus(Activity.ActivityStatus.processing);
            activityDTO.setActivityStatus("processing");
        }
        activityRepository.saveAndFlush(activity);
        return activityDTO;
    }

    /**
     * 更新活动信息
     *
     * @param requestBody
     * @param activityId
     * @return
     * @throws ActivityException
     */
    public String updateActivity(ActivityRequest requestBody, String activityId) throws ActivityException {
        Activity activity = activityRepository.findByIdAndRemove(activityId, 0);
        if (activity == null) {
            throw new ActivityException("活动不存在");
        }

        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtil.copyProperties(requestBody, activity, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        activity.setUpdateTime(DateUtils.currentDate());

        //查看活动状态
        Date startTime = DateUtils.parseStr2Date("yyyy-MM-dd", requestBody.getStartTime());
        Date endTime = DateUtils.parseStr2Date("yyyy-MM-dd", requestBody.getEndTime());
        Date nowTime = new Date();

        if (nowTime.before(startTime)) {
            //状态准备中
            activity.setActivityStatus(Activity.ActivityStatus.preparing);
        } else if (nowTime.after(endTime)) {
            activity.setActivityStatus(Activity.ActivityStatus.over);

        } else {
            activity.setActivityStatus(Activity.ActivityStatus.processing);
        }

        activityRepository.save(activity);

        if (utils.StringUtils.isNotEmpty(requestBody.getImageId())) {
            bandingImageShip(activity.getId(), requestBody.getImageId());
        }
        return "修改活动成功";
    }


    /**
     * 删除活动
     *
     * @param activityId
     * @return
     * @throws ActivityException
     */
    public String removeActivity(String activityId) throws ActivityException {
        Activity activity = activityRepository.findByIdAndRemove(activityId, 0);
        if (activity == null) {
            throw new ActivityException("活动不存在");
        }
        activity.setRemove(1);
        activityRepository.save(activity);
        return "删除成功";

    }

    /**
     * 将活动设置为不显示
     *
     * @param activityId
     * @return
     * @throws ActivityException
     */
    public String setNotShow(String activityId) throws ActivityException {
        Activity activity = activityRepository.findByIdAndRemove(activityId, 0);
        if (activity == null) {
            throw new ActivityException("活动不存在");
        }
        activity.setShow(1);
        activityRepository.save(activity);
        return "设置隐藏成功";

    }

    /**
     * 后台管理分页查询活动
     *
     * @param requestBody
     * @return
     */
    public PageDTO<Activity> allActivityForManagement(ActivityRequest requestBody) throws ActivityException {
        Integer size = requestBody.getSize();
        Integer page = requestBody.getPage();
        String fromDate = requestBody.getFromDate();
        String toDate = requestBody.getToDate();
        String activityStatus = requestBody.getActivityStatus();
        String activityType = requestBody.getActivityType();
        String keyword = requestBody.getKeyword();
        List<Activity> list = null;
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        Pageable pageable = PageRequest.of(page, size, sort);
        Page<Activity> activities = activityRepository.findAll((Specification<Activity>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            // 创建具体查询条件
            if (StringUtil.isNotEmpty(keyword)) {
                Predicate p = criteriaBuilder.like(root.get("activityName").as(String.class), "%" + keyword + "%");
                predicates.add(p);
            }


            if (StringUtil.isNotEmpty(fromDate)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(fromDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(toDate)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(toDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }

            if (StringUtil.isNotEmpty(activityType)) {
                switch (activityType) {
                    case PROMOTION:
                        predicates.add(criteriaBuilder.equal(root.get("activityType").as(Activity.ActivityTypes.class), Activity.ActivityTypes.stage));
                        break;
                    case THEME:
                        predicates.add(criteriaBuilder.equal(root.get("activityType").as(Activity.ActivityTypes.class), Activity.ActivityTypes.theme));
                        break;
                    case APPLY:
                        predicates.add(criteriaBuilder.equal(root.get("activityType").as(Activity.ActivityTypes.class), Activity.ActivityTypes.apply));
                        break;
                    default:

                }
            }
            if (StringUtil.isNotEmpty(activityStatus)) {
                switch (activityStatus) {
                    case PREPARING:
                        predicates.add(criteriaBuilder.equal(root.get("activityStatus").as(Activity.ActivityStatus.class), Activity.ActivityStatus.preparing));
                        break;
                    case PROCESSING:
                        predicates.add(criteriaBuilder.equal(root.get("activityStatus").as(Activity.ActivityStatus.class), Activity.ActivityStatus.processing));

                        break;
                    case OVER:
                        predicates.add(criteriaBuilder.equal(root.get("activityStatus").as(Activity.ActivityStatus.class), Activity.ActivityStatus.over));
                        break;
                    default:
                }
            }
            predicates.add(criteriaBuilder.equal(root.get("remove"), 0));

            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);


        if ((activities.getSize()) == 0) {
            throw new ActivityException("活动列表查询失败");
        }
        PageDTO<Activity> pageDTO = new PageDTO<>();
        pageDTO.setTotal(activities.getTotalElements());
        pageDTO.setList(activities.getContent());
        pageDTO.setTotalPage(activities.getTotalPages());
        pageDTO.setPage(page);
        pageDTO.setPageSize(size);
        pageDTO.setFromDate(fromDate);
        pageDTO.setToDate(toDate);
        pageDTO.setKeyword(keyword);
        pageDTO.setActivityStatus(activityStatus);
        pageDTO.setActivityType(activityType);
        return pageDTO;

    }


    /**
     * 根据楼层id查看楼层信息
     *
     * @param request
     * @return
     */
    public ActivityDTO query(ActivityRequest request) {
        Activity activity = activityRepository.findByIdAndRemove(request.getActivityId(), 0);

        ActivityDTO activityDTO = new ActivityDTO();
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtil.copyProperties(activity, activityDTO, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));


        return activityDTO;
    }

    /**
     * 根据活动名称查询活动（活动名字校验）
     *
     * @param activityName
     */
    public boolean findActivityByName(String activityName) {

        Activity activity = activityRepository.findActivityByActivityNameAndRemove(activityName, 0);
        if (activity != null) {
            return false;
        }
        return true;
    }

    //每个整点后更新活动状态
    @Scheduled(cron = "0 0 * * *  ?")
    public void updateActivityStatus() {
        List<Activity> activities = activityRepository.findAllByRemove(0);
        List<String> activityIds = activities.stream().map(Activity::getId).collect(Collectors.toList());
        if (activities.isEmpty()) {
            return;
        }
        List<Activity> activityList = activityRepository.findAllByIdIn(activityIds);
        if (activityList.isEmpty()) {
            return;
        }
        activityList.forEach(activity -> {
            Date startTime = DateUtils.strToDate(activity.getStartTime(), DateUtils.DATE);
            Date endTime = DateUtils.strToDate(activity.getEndTime(), DateUtils.DATE);
            Date nowTime = new Date();
            if (nowTime.before(startTime)) {
                activity.setActivityStatus(Activity.ActivityStatus.preparing);
            } else if (nowTime.after(endTime)) {
                activity.setActivityStatus(Activity.ActivityStatus.over);
            } else {
                activity.setActivityStatus(Activity.ActivityStatus.processing);
            }
        });
        activityRepository.saveAll(activityList);
    }

    public List<ActivityDTO> list() {
        List<ActivityDTO> activityDTOS = new LinkedList<>();
        List<Activity> activities = activityRepository.findAllByRemove(0);
        for (Activity activity : activities) {
            ActivityDTO activityDTO = new ActivityDTO();
            BeanUtils.copyProperties(activity, activityDTO);
            activityDTOS.add(activityDTO);
        }
        return activityDTOS;
    }

}


